package com.itfsw.jenkins.plugins;

import com.qiniu.cdn.CdnManager;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.storage.model.FileListing;
import com.qiniu.util.Auth;
import com.qiniu.util.StringUtils;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Publisher;
import hudson.tasks.Recorder;
import org.kohsuke.stapler.DataBoundConstructor;

import java.io.IOException;
import java.io.PrintStream;

/**
 * {Description}
 *
 * @author HW
 * @date 2021/12/10 15:05
 */
public class QiniuCleaner extends Recorder {
    private String bucket, prefix;

    /**
     * 构造函数
     *
     * @param bucket
     * @param prefix
     */
    @DataBoundConstructor
    public QiniuCleaner(String bucket, String prefix) {
        this.bucket = bucket;
        this.prefix = prefix;
    }

    @Override
    public BuildStepMonitor getRequiredMonitorService() {
        return BuildStepMonitor.STEP;
    }

    @Override
    public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
        PrintStream logger = listener.getLogger();
        if (build.getResult() == Result.SUCCESS) {
            // 密钥配置
            QiniuConfiguration configuration = QiniuConfiguration.get();
            Auth auth = Auth.create(configuration.getAccessKey(), configuration.getSecretKeyPlainText());
            Configuration config = new Configuration();
            // 空间管理
            BucketManager bucketManager = new BucketManager(auth, config);

            String marker = null;
            do {
                FileListing fileListing = bucketManager.listFilesV2(getBucket(), getPrefix(), marker, 1000, null);
                if (fileListing.items.length > 0) {
                    // 批量清理
                    BucketManager.BatchOperations operations = new BucketManager.BatchOperations();
                    for (FileInfo fileInfo : fileListing.items) {
                        logger.println("清理七牛文件：" + fileInfo.key);
                        operations.addDeleteOp(getBucket(), fileInfo.key);
                    }
                    bucketManager.batch(operations);
                }
                marker = fileListing.marker;
            } while (!StringUtils.isNullOrEmpty(marker));
            return true;
        }
        return false;
    }

    /**
     * Getter method for property <tt>bucket</tt>.
     *
     * @return property value of bucket
     */
    public String getBucket() {
        return bucket;
    }

    /**
     * Getter method for property <tt>prefix</tt>.
     *
     * @return property value of prefix
     */
    public String getPrefix() {
        return prefix;
    }

    /**
     * 在 Jenkins 的插件中，每一个插件类中都必须要有一个 ==Descriptor 内部静态类==，它代表一个类的 ’描述者‘，用于指明这是一个扩展点的实现，Jenkins 是通过这个描述者才能知道我们自己写的插件。
     * <p>
     * 每一个 ‘描述者’ 静态类都需要被 @Extension注解，Jenkins 内部会扫描 @Extenstion 注解来知道注册了有哪些插件。
     * <p>
     * 作者：PC_Repair
     * 链接：https://www.jianshu.com/p/cae571c56c30
     * 来源：简书
     * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
     */
    @Extension
    public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> {
        @Override
        public boolean isApplicable(Class<? extends AbstractProject> jobType) {
            return true;
        }

        /**
         * 显示名称
         *
         * @return
         */
        @NonNull
        @Override
        public String getDisplayName() {
            return "清理七牛";
        }
    }
}
